//go:build linux
// +build linux

package lscpu

import (
	"encoding/json"
	"github.com/shirou/gopsutil/v3/cpu"
	"os/exec"
	"regexp"
	"strconv"
)

type LSCPU struct {
	Lscpu []*LSField `json:"lscpu"`
}

type LSField struct {
	Field    string     `json:"field"`
	Data     string     `json:"data"`
	Children []*LSField `json:"children,omitempty"`
}

func GetLSCPU() (*LSCPU, error) {
	command := exec.Command("lscpu", "--json")
	command.Env = append(command.Env, "LANG=C")
	out, err := command.Output()
	if err != nil {
		return nil, err
	}
	lscpu := &LSCPU{}
	err = json.Unmarshal(out, lscpu)
	return lscpu, err
}

func GetCPUInfo() (*CPUInfo, error) {
	lscpu, err := GetLSCPU()
	if err != nil {
		return nil, err
	}
	ci := &CPUInfo{}
	for _, l := range lscpu.Lscpu {
		switch l.Field {
		case "Architecture:":
			ci.Arch = l.Data
		case "Model name:":
			ci.ModelName = l.Data
		case "Socket(s):":
			ci.Num, err = strconv.Atoi(l.Data)
		case "Core(s) per socket:":
			ci.Core, err = strconv.Atoi(l.Data)
		case "CPU(s):":
			ci.Processor, err = strconv.Atoi(l.Data)
		case "Vendor ID:":
			ci.Vendor = l.Data
		}
	}
	ci.Core = ci.Core * ci.Num
	// 根据 @ 分割cpu频率
	re := regexp.MustCompile(`@ (.+)`)
	matches := re.FindStringSubmatch(ci.ModelName)
	if len(matches) < 2 {
		info, err := cpu.Info()
		if err != nil {
			return nil, err
		}
		float := strconv.FormatFloat(info[0].Mhz, 'f', 2, 64)
		ci.Speed = float + " MHz"
	} else {
		ci.Speed = matches[1]
	}
	return ci, err
}
